home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
DEMON
/
RISCOS2
/
TCP_131S.ARC
/
c
/
AX25USER
< prev
next >
Wrap
Text File
|
1992-03-07
|
5KB
|
173 lines
/* User subroutines for AX.25 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>
#include "global.h"
#include "mbuf.h"
#include "timer.h"
#include "iface.h"
#include "ax25.h"
#include "lapb.h"
/* Open an AX.25 connection */
struct ax25_cb *open_ax25(struct ax25 *addr, int16 window,
void (*r_upcall)(), void (*t_upcall)(),
void (*s_upcall)(),
struct interface *iface, char *user)
{
struct ax25_cb *axp;
if((axp = cr_ax25(&addr->dest)) == NULLAX25)
return NULLAX25;
axp->addr = *addr;
if(addr->ndigis != 0){
axp->t1.start *= (addr->ndigis + 1);
axp->t2.start *= (addr->ndigis + 1);
axp->t3.start *= (addr->ndigis + 1);
}
axp->window = window;
axp->r_upcall = r_upcall;
axp->t_upcall = t_upcall;
axp->s_upcall = s_upcall;
axp->interface = iface;
axp->user = user;
switch(axp->state){
case DISCONNECTED:
/* Don't send anything if the connection already exists */
est_link(axp);
lapbstate(axp,SETUP);
break;
case SETUP:
free_q(&axp->txq);
break;
case DISCPENDING: /* Ignore */
case FRAMEREJECT:
break;
case RECOVERY:
case CONNECTED:
free_q(&axp->txq);
est_link(axp);
lapbstate(axp,SETUP);
break;
}
return axp;
}
/* Send data on an AX.25 connection. Caller must provide PID */
int send_ax25(struct ax25_cb *axp, struct mbuf *bp)
{
if(axp == NULLAX25 || bp == NULLBUF)
return -1;
enqueue(&axp->txq,bp);
return lapb_output(axp);
}
/* Do printf on a ax25 connection */
int aprintf(struct ax25_cb *axp, char *message, ...)
{
va_list argptr;
struct mbuf *bp;
int len;
register char *cp;
if(axp == NULLAX25)
return 0;
if((bp = alloc_mbuf(axp->paclen+1)) != NULLBUF)
{
va_start(argptr,message);
cp = bp->data;
*cp++ = PID_NO_L3;
len = vsprintf(cp,message,argptr);
va_end(argptr);
cp = bp->data;
cp++;
bp->cnt = (strlen(cp) + 1);
send_ax25(axp,bp);
return len;
}
else
{
return 0;
}
}
/* Receive incoming data on an AX.25 connection */
struct mbuf *recv_ax25(register struct ax25_cb *axp, int16 cnt)
{
struct mbuf *bp;
cnt = cnt;
if(axp->rxq == NULLBUF)
return NULLBUF;
bp = axp->rxq;
axp->rxq = NULLBUF;
/* If this has un-busied us, send a RR to reopen the window */
if(len_mbuf(bp) >= axp->window)
sendctl(axp,RESPONSE,RR);
return bp;
}
/* Close an AX.25 connection */
void disc_ax25(struct ax25_cb *axp)
{
switch(axp->state){
case DISCONNECTED:
break; /* Ignored */
case SETUP:
free_q(&axp->txq);
case DISCPENDING:
lapbstate(axp,DISCONNECTED);
del_ax25(axp);
break;
case CONNECTED:
case RECOVERY:
case FRAMEREJECT:
free_q(&axp->txq);
axp->retries = 0;
sendctl(axp,COMMAND,DISC|PF);
stop_timer(&axp->t3);
start_timer(&axp->t1);
lapbstate(axp,DISCPENDING);
break;
}
}
/* Verify that axp points to a valid ax25 control block */
int ax25val(struct ax25_cb *axp)
{
register struct ax25_cb *axp1;
register int i;
if(axp == NULLAX25)
return 0; /* Null pointer can't be valid */
for(i=0; i < NHASH; i++)
for(axp1 = ax25_cb[i];axp1 != NULLAX25; axp1 = axp1->next)
if(axp1 == axp)
return 1;
return 0;
}
/* Force a retransmission */
int kick_ax25(struct ax25_cb *axp)
{
if(!ax25val(axp))
return -1;
recover((int *)axp);
return 0;
}
/* Abruptly terminate an AX.25 connection */
void reset_ax25(struct ax25_cb *axp)
{
lapbstate(axp,DISCONNECTED);
del_ax25(axp);
}